//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.wsd.smartcarwasher.service;

import cn.hutool.core.exceptions.StatefulException;
import com.wsd.smartcarwasher.constans.Constant;
import com.wsd.smartcarwasher.constans.ResultState;
import com.wsd.smartcarwasher.domain.*;
import com.wsd.smartcarwasher.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;

import java.text.DecimalFormat;
import java.util.*;
import java.util.Map.Entry;

import static com.wsd.smartcarwasher.constans.Constant.REFUND_URL;

@Service
public class WxPayService {
    private static final Logger logger = LoggerFactory.getLogger(WxPayService.class);

    @Autowired
    private  CardOrderService cardOrderService;

    public WxPayService() {
    }

    private String unifiedOrder(PayInfo payInfo) {
        logger.info("openId=" + payInfo.getOpenid());
        try {
            String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            String md5 = this.getSign(payInfo);
            payInfo.setSign(md5);
            String xml = CommonUtil.payInfoToXML(payInfo);
            logger.info("xml=" + xml);
            StringBuffer buffer = HttpUtil.httpsRequest(url, "POST", xml);
            Map<String, String> result = CommonUtil.parseXml(buffer.toString());
            String return_code = (String)result.get("return_code");
            String return_msg = (String)result.get("return_msg");
            if (StringUtils.isNotBlank(return_code) && return_code.equals("SUCCESS")) {
                if (StringUtils.isNotBlank(return_msg) && return_msg.equals("OK")) {
                    if (result.containsKey("prepay_id")) {
                        return (String)result.get("prepay_id");
                    }

                    String errorCodeDes = (String)result.get("err_code_des");
                    logger.info("创建预支付订单失败，原因" + errorCodeDes);
                } else {
                    logger.info("统一下单错误: " + return_msg);
                }
            } else {
                logger.info("统一下单请求失败: " + result.toString());
            }
        } catch (Exception var10) {
            logger.error("catch error:", var10);
        }

        return "";
    }

    private Map<String, String> refundOrder(Refundnfo payInfo) throws Exception {
           String url = Constant.REFUND_URL;
           String md5 = this.getSignByRefund(payInfo);
           payInfo.setSign(md5);
           String xml = CommonUtil.refundInfoToXML(payInfo);
           CloseableHttpResponse response =  HttpUtil.Post(url, xml, true);
           String transfersXml = EntityUtils.toString(response.getEntity(), "utf-8");
           return CommonUtil.parseXml(transfersXml);
    }

    public ModelMap payByWx(String openId, String clientIP, Order order) {

        String randomNonceStr = RandomUtils.generateMixString(32);
        PayInfo payInfo = this.createPayInfo(openId, clientIP, randomNonceStr, order);
        String prepayId = this.unifiedOrder(payInfo);
        if (StringUtils.isBlank(prepayId)) {
            return ReturnUtil.Error(ResultState.CREATE_PAY_ORDER_FAIL.getMsg());
        } else {
            Map<String, String> map = this.generateAppCallParam(randomNonceStr, prepayId, order);
            return ReturnUtil.Success(ResultState.CREATE_PAY_ORDER_SUCCESS.getMsg(), map);
        }
    }


    /**
     * 充值订单微信支付
     * @param openId
     * @param clientIP
     * @param chargeRecord
     * @return
     */
    public Map<String, String> payByWxForCharge(String openId, String clientIP, TChargeRecord chargeRecord) {

        String randomNonceStr = RandomUtils.generateMixString(32);
        PayInfo payInfo = this.createChargePayInfo(openId, clientIP, randomNonceStr, chargeRecord);
        String prepayId = this.unifiedOrder(payInfo);
        if (StringUtils.isBlank(prepayId)) {
            throw new StatefulException(402,"支付订单创建异常");
        } else {
            Map<String, String> map = this.generateChargeOrderParam(randomNonceStr, prepayId, chargeRecord);
            return map;
        }
    }



    public ModelMap refundByWx(CardOrder order) throws Exception {
        String randomNonceStr = RandomUtils.generateMixString(32);
        Refundnfo refundInfo = this.createRefundInfo(randomNonceStr, order);
        Map map = this.refundOrder(refundInfo);
        if (StringUtil.isNullOrEmpty(map)) {
            return ReturnUtil.Error(ResultState.CREATE_REFUND_ORDER_ERROR.getMsg());
        } else {
            return ReturnUtil.Success(ResultState.CREATE_REFUND_ORDER_SUCCESS.getMsg(), map);
        }
    }


    public ModelMap friendPayByWx(String openId, String clientIP, Order order, UserInfo user,String ucId) {
        String randomNonceStr = RandomUtils.generateMixString(32);
        PayInfo payInfo = this.createPayInfo(openId, clientIP, randomNonceStr, order);
        String prepayId = this.unifiedOrder(payInfo);
        if (StringUtils.isBlank(prepayId)) {
            return ReturnUtil.Error(ResultState.CREATE_PAY_ORDER_FAIL.getMsg());
        } else {
            Map<String, String> map = this.generateAppCallParam(randomNonceStr, prepayId, order);
            CardOrder cardOrder=this.cardOrderService.queryOrderInfoByUcId(ucId);
            cardOrder.setIsHepaid(1);
            cardOrder.setHeuserId(user.getUserId());
            this.cardOrderService.updateCardOrder(cardOrder);
            return ReturnUtil.Success(ResultState.CREATE_PAY_ORDER_SUCCESS.getMsg(), map);
        }
    }



    private PayInfo createPayInfo(String openId, String clientIP, String randomNonceStr, Order order) {
        Date date = new Date();
        String timeStart = TimeUtils.getFormatTime(date, "yyyyMMddHHmmss");
        String timeExpire = TimeUtils.getFormatTime(TimeUtils.addDay(date, 2), "yyyyMMddHHmmss");
        PayInfo payInfo = new PayInfo();
        payInfo.setAppid(Constant.APP_ID);
        payInfo.setMch_id("1532344341");
        payInfo.setDevice_info("WEB");
        payInfo.setNonce_str(randomNonceStr);
        payInfo.setSign_type("MD5");
        payInfo.setBody("漫蜗智能洗车-服务购买");
        payInfo.setAttach("支付测试");
        payInfo.setOut_trade_no(order.getOrderSn());
        payInfo.setTotal_fee(changeY2F(order.getPayPrice().doubleValue()));
        payInfo.setSpbill_create_ip(clientIP);
        payInfo.setTime_start(timeStart);
        payInfo.setTime_expire(timeExpire);
        payInfo.setNotify_url(Constant.URL_NOTIFY);
        payInfo.setTrade_type("JSAPI");
        payInfo.setLimit_pay("no_credit");
        payInfo.setOpenid(openId);
        return payInfo;
    }


    /**
     * 创建充值订单的实体
     * @param openId
     * @param clientIP
     * @param randomNonceStr
     * @param order
     * @return
     */
    private PayInfo createChargePayInfo(String openId, String clientIP, String randomNonceStr, TChargeRecord order) {
        Date date = new Date();
        String timeStart = TimeUtils.getFormatTime(date, "yyyyMMddHHmmss");
        String timeExpire = TimeUtils.getFormatTime(TimeUtils.addDay(date, 2), "yyyyMMddHHmmss");
        PayInfo payInfo = new PayInfo();
        payInfo.setAppid(Constant.APP_ID);
        payInfo.setMch_id("1532344341");
        payInfo.setDevice_info("WEB");
        payInfo.setNonce_str(randomNonceStr);
        payInfo.setSign_type("MD5");
        payInfo.setBody("漫蜗智能洗车-钱包充值");
        payInfo.setAttach("钱包充值");
        payInfo.setOut_trade_no(order.getTransactionNo());
        payInfo.setTotal_fee(changeY2F(order.getPrice().doubleValue()));
        payInfo.setSpbill_create_ip(clientIP);
        payInfo.setTime_start(timeStart);
        payInfo.setTime_expire(timeExpire);
        payInfo.setNotify_url(Constant.CHARGE_URL_NOTIFY);
        payInfo.setTrade_type("JSAPI");
        payInfo.setLimit_pay("no_credit");
        payInfo.setOpenid(openId);
        return payInfo;
    }







    private Refundnfo createRefundInfo(String randomNonceStr, CardOrder cardOrder) {
        Date date = new Date();
        Refundnfo payInfo = new Refundnfo();
        payInfo.setAppid(Constant.APP_ID);
        payInfo.setMch_id("1532344341");
        payInfo.setNotify_url(Constant.URL_REFUND_NOTIFY_URL);
        payInfo.setNonce_str(randomNonceStr);
        payInfo.setOp_user_id(Constant.MCH_ID);
        payInfo.setOut_refund_no(cardOrder.getOrderSn());
        payInfo.setOut_trade_no(cardOrder.getOrderSn());
        payInfo.setRefund_fee(changeY2F(cardOrder.getPayPrice().doubleValue()));
        payInfo.setTotal_fee(changeY2F(cardOrder.getPayPrice().doubleValue()));
        return payInfo;
    }













    /**
     * 元转分，确保price保留两位有效数字
     * @return
     */
    public static int changeY2F(double price) {
        DecimalFormat df = new DecimalFormat("#.00");
        price = Double.valueOf(df.format(price));
        int money = (int)(price * 100);
        return money;
    }

    private String getSign(PayInfo payInfo) throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append("appid=" + payInfo.getAppid())
                .append("&attach=" + payInfo.getAttach())
                .append("&body=" + payInfo.getBody())
                .append("&device_info=" + payInfo.getDevice_info())
                .append("&limit_pay=" + payInfo.getLimit_pay())
                .append("&mch_id=" + payInfo.getMch_id())
                .append("&nonce_str=" + payInfo.getNonce_str())
                .append("&notify_url=" + payInfo.getNotify_url())
                .append("&openid=" + payInfo.getOpenid())
                .append("&out_trade_no=" + payInfo.getOut_trade_no())
                .append("&sign_type=" + payInfo.getSign_type())
                .append("&spbill_create_ip=" + payInfo.getSpbill_create_ip())
                .append("&time_expire=" + payInfo.getTime_expire())
                .append("&time_start=" + payInfo.getTime_start())
                .append("&total_fee=" + payInfo.getTotal_fee())
                .append("&trade_type=" + payInfo.getTrade_type())
                .append("&key=woniuzhinengkejiyouxiangongsi000");
        return CommonUtil.getMD5(sb.toString().trim()).toUpperCase();
    }


    private String getSignByRefund(Refundnfo payInfo) throws Exception {
        StringBuffer sb = new StringBuffer();
                sb.append("appid=" + payInfo.getAppid())
                .append("&mch_id=" + payInfo.getMch_id())
                .append("&nonce_str=" + payInfo.getNonce_str())
                 .append("&notify_url="+payInfo.getNotify_url())
                 .append("&op_user_id="+payInfo.getOp_user_id())
                .append("&out_refund_no=" + payInfo.getOut_refund_no())
                .append("&out_trade_no=" + payInfo.getOut_trade_no())
                .append("&refund_fee=" + payInfo.getTotal_fee())
                .append("&total_fee=" + payInfo.getTotal_fee())
                .append("&key=woniuzhinengkejiyouxiangongsi000");
        return CommonUtil.getMD5(sb.toString().trim()).toUpperCase();
    }



    private String getSign(SortedMap<String, String> packageParams) throws Exception {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();

        while(it.hasNext()) {
            Entry entry = (Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }

        sb.append("key=woniuzhinengkejiyouxiangongsi000");
        return CommonUtil.getMD5(sb.toString().trim()).toUpperCase();
    }

    public boolean isWxPaySign(Map<String, String> map) {
        String signFromAPIResponse = (String)map.get("sign");
        if (signFromAPIResponse != null && !signFromAPIResponse.equals("")) {
            SortedMap<String, String> packageParams = new TreeMap();
            Iterator var4 = map.keySet().iterator();

            String wxPaySign;
            while(var4.hasNext()) {
                wxPaySign = (String)var4.next();
                String parameterValue = (String)map.get(wxPaySign);
                String v = null != parameterValue ? parameterValue.trim() : "";
                packageParams.put(wxPaySign, v);
            }

            String resultSign;
            try {
                resultSign = this.getSign((SortedMap)packageParams);
            } catch (Exception var8) {
                logger.error("根据微信支付返回数据计算签名失败", var8);
                return false;
            }

            wxPaySign = ((String)packageParams.get("sign")).toUpperCase();
            return wxPaySign.equals(resultSign);
        } else {
            logger.error("API返回的数据签名数据不存在，有可能被第三方篡改!!!");
            return false;
        }
    }

    private Map<String, String> generateAppCallParam(String randomStr, String prepayId, Order order) {
        SortedMap<String, String> returnMap = new TreeMap();
        returnMap.put("appId", Constant.APP_ID);
        returnMap.put("package", "prepay_id=" + prepayId);
        returnMap.put("nonceStr", randomStr);
        returnMap.put("signType", "MD5");
        returnMap.put("timeStamp", String.valueOf((new Date()).getTime()));
        String sign = null;
        try {
            sign = this.getSign((SortedMap)returnMap);
        } catch (Exception var7) {
            logger.error("创建签名失败", var7);
        }
        returnMap.put("paySign", sign);
        returnMap.remove("appId");
        returnMap.put("orderSn", order.getOrderSn());
        return returnMap;
    }


    /**
     * 生成充值订单时的一些必要参数
     * @param randomStr
     * @param prepayId
     * @param order
     * @return
     */
    private Map<String, String> generateChargeOrderParam(String randomStr, String prepayId, TChargeRecord order) {
        SortedMap<String, String> returnMap = new TreeMap();
        returnMap.put("appId", Constant.APP_ID);
        returnMap.put("package", "prepay_id=" + prepayId);
        returnMap.put("nonceStr", randomStr);
        returnMap.put("signType", "MD5");
        returnMap.put("timeStamp", String.valueOf((new Date()).getTime()));
        String sign = null;
        try {
            sign = this.getSign((SortedMap)returnMap);
        } catch (Exception var7) {
            logger.error("创建签名失败", var7);
        }
        returnMap.put("paySign", sign);
        returnMap.remove("appId");
        returnMap.put("orderSn", order.getTransactionNo());
        return returnMap;
    }




    private Map<String, String> generateAppRefundParam(String randomStr, String prepayId, Order order) {
        SortedMap<String, String> returnMap = new TreeMap();
        returnMap.put("appId", Constant.APP_ID);
        returnMap.put("package", "prepay_id=" + prepayId);
        returnMap.put("mch_id",Constant.MCH_ID);
        returnMap.put("nonceStr", randomStr);
        returnMap.put("signType", "MD5");
        returnMap.put("timeStamp", String.valueOf((new Date()).getTime()));
        String sign = null;
        try {
            sign = this.getSign((SortedMap)returnMap);
        } catch (Exception var7) {
            logger.error("创建签名失败", var7);
        }
        returnMap.put("paySign", sign);
        returnMap.remove("appId");
        returnMap.put("orderSn", order.getOrderSn());
        return returnMap;
    }


    public static void main(String[] args) {
       // System.out.println(changeY2F(new BigDecimal(0.01).doubleValue()));
    }
}

/*
package com.wsd.smartcarwasher.service;

import com.wsd.smartcarwasher.constans.Constant;
import com.wsd.smartcarwasher.constans.ResultState;
import com.wsd.smartcarwasher.domain.Order;
import com.wsd.smartcarwasher.domain.PayInfo;
import com.wsd.smartcarwasher.util.CommonUtil;
import com.wsd.smartcarwasher.util.HttpUtil;
import com.wsd.smartcarwasher.util.RandomUtils;
import com.wsd.smartcarwasher.util.ReturnUtil;
import com.wsd.smartcarwasher.util.TimeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;

import java.math.BigDecimal;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

@Service
public class WxPayService {
    private static final Logger logger = LoggerFactory.getLogger(WxPayService.class);

    */
/**
     * 调用统一下单接口
     *
     * @param payInfo 支付订单信息
     *//*

    private String unifiedOrder(PayInfo payInfo) {
        logger.info("openId=" + payInfo.getOpenid());
        try {
            String url = Constant.URL_UNIFIED_ORDER;
            String md5 = getSign(payInfo);
            payInfo.setSign(md5);

            String xml = CommonUtil.payInfoToXML(payInfo);
            logger.info("xml=" + xml);
            StringBuffer buffer = HttpUtil.httpsRequest(url, "POST", xml);
            Map<String, String> result = CommonUtil.parseXml(buffer.toString());

            String return_code = result.get("return_code");
            String return_msg = result.get("return_msg");
            if (StringUtils.isNotBlank(return_code) && return_code.equals("SUCCESS")) {
                if (StringUtils.isNotBlank(return_msg) && return_msg.equals("OK")) {
                    if (result.containsKey("prepay_id")) {
                        return result.get("prepay_id");
                    } else {
                        String errorCodeDes = result.get("err_code_des");
                        logger.info("创建预支付订单失败，原因" + errorCodeDes);
                    }
                } else {
                    logger.info("统一下单错误: " + return_msg);
                }
            } else {
                logger.info("统一下单请求失败: " + result.toString());
            }
        } catch (Exception e) {
            logger.error("catch error:", e.getMessage());
        }
        return "";
    }

    public ModelMap payByWx(String openId, String clientIP, Order order) {
        String randomNonceStr = RandomUtils.generateMixString(32);
        PayInfo payInfo = createPayInfo(openId, clientIP, randomNonceStr, order);
        String prepayId = unifiedOrder(payInfo);
        if (StringUtils.isBlank(prepayId)) {
            return ReturnUtil.Error(ResultState.CREATE_PAY_ORDER_FAIL.getMsg());
        }
        Map<String, String> map = generateAppCallParam(randomNonceStr, prepayId, order);
        return ReturnUtil.Success(ResultState.CREATE_PAY_ORDER_SUCCESS.getMsg(), map);
    }

    private PayInfo createPayInfo(String openId, String clientIP, String randomNonceStr, Order order) {

        Date date = new Date();
        String timeStart = TimeUtils.getFormatTime(date, Constant.TIME_FORMAT);
        String timeExpire = TimeUtils.getFormatTime(TimeUtils.addDay(date, Constant.TIME_EXPIRE), Constant.TIME_FORMAT);

        PayInfo payInfo = new PayInfo();
        payInfo.setAppid(Constant.APP_ID);
        payInfo.setMch_id(Constant.MCH_ID);
        payInfo.setDevice_info("WEB");
        payInfo.setNonce_str(randomNonceStr);
        payInfo.setSign_type("MD5");  //默认即为MD5
        payInfo.setBody("漫蜗智能洗车-服务购买");
        payInfo.setAttach("支付测试");
        payInfo.setOut_trade_no(order.getOrderSn());
//        payInfo.setTotal_fee(order.getPayPrice().multiply(new BigDecimal(100)).intValue());
        payInfo.setTotal_fee(1);
        payInfo.setSpbill_create_ip(clientIP);
        payInfo.setTime_start(timeStart);
        payInfo.setTime_expire(timeExpire);
        payInfo.setNotify_url(Constant.URL_NOTIFY);
        payInfo.setTrade_type("JSAPI");
        payInfo.setLimit_pay("no_credit");
        payInfo.setOpenid(openId);

        return payInfo;
    }

    private String getSign(PayInfo payInfo) throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append("appid=" + payInfo.getAppid())
                .append("&attach=" + payInfo.getAttach())
                .append("&body=" + payInfo.getBody())
                .append("&device_info=" + payInfo.getDevice_info())
                .append("&limit_pay=" + payInfo.getLimit_pay())
                .append("&mch_id=" + payInfo.getMch_id())
                .append("&nonce_str=" + payInfo.getNonce_str())
                .append("&notify_url=" + payInfo.getNotify_url())
                .append("&openid=" + payInfo.getOpenid())
                .append("&out_trade_no=" + payInfo.getOut_trade_no())
                .append("&sign_type=" + payInfo.getSign_type())
                .append("&spbill_create_ip=" + payInfo.getSpbill_create_ip())
                .append("&time_expire=" + payInfo.getTime_expire())
                .append("&time_start=" + payInfo.getTime_start())
                .append("&total_fee=" + payInfo.getTotal_fee())
                .append("&trade_type=" + payInfo.getTrade_type())
                .append("&key=" + Constant.APP_KEY);
        return CommonUtil.getMD5(sb.toString().trim()).toUpperCase();
    }

    private String getSign(SortedMap<String, String> packageParams) throws Exception {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + Constant.APP_KEY);
        return CommonUtil.getMD5(sb.toString().trim()).toUpperCase();
    }

    */
/**
     * 验证回调签名
     *
     * @return
     *//*

    public boolean isWxPaySign(Map<String, String> map) {

        String signFromAPIResponse = map.get("sign");
        if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {
            logger.error("API返回的数据签名数据不存在，有可能被第三方篡改!!!");
            return false;
        }
        //过滤空 设置 TreeMap
        SortedMap<String, String> packageParams = new TreeMap<>();
        for (String parameter : map.keySet()) {
            String parameterValue = map.get(parameter);
            String v = null != parameterValue ? parameterValue.trim() : "";
            packageParams.put(parameter, v);
        }

        //将API返回的数据根据用签名算法进行计算新的签名，用来跟API返回的签名进行比较
        //算出签名
        String resultSign;
        try {
            resultSign = getSign(packageParams);
        } catch (Exception e) {
            logger.error("根据微信支付返回数据计算签名失败");
            return false;
        }

        String wxPaySign = packageParams.get("sign").toUpperCase();
        return wxPaySign.equals(resultSign);
    }

    private Map<String, String> generateAppCallParam(String randomStr, String prepayId, Order order) {
        SortedMap<String, String> returnMap = new TreeMap<>();
        returnMap.put("appId", Constant.APP_ID);
        returnMap.put("package", "prepay_id=" + prepayId);
        returnMap.put("nonceStr", randomStr);
        returnMap.put("signType", "MD5");
        returnMap.put("timeStamp", String.valueOf(new Date().getTime()));
        String sign = null;
        try {
            sign = getSign(returnMap);
        } catch (Exception e) {
            logger.error("创建签名失败");
        }
        returnMap.put("paySign", sign);
        returnMap.remove("appId");
        returnMap.put("orderSn", order.getOrderSn());
        return returnMap;
    }
}
*/
